package org.ccay.security.util;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.ccay.security.annotation.SecurityPolicy;
import org.ccay.security.exception.AuthenticationException;
import org.ccay.security.exception.AuthorizationException;

public class SecurityUtil {
	
	/**
	 * 校验是否登录且有权限
	 * 此方法不返回值，如果没有权限则抛出AuthenticationException
	 * @param permission
	 */
	public static void checkPermission(String permission){
		checkPermission(permission,SecurityPolicy.Required);
	}

	/**
	 * 校验是否登录且有权限
	 * @param permission
	 * @return 是否有权限
	 */
	public static boolean checkPermissionNoThrowsException(String permission){
		return checkPermissionNoThrowsException(permission,SecurityPolicy.Required);
	}
	
	/**
	 * 校验是有权限
	 * @param permission
	 * @return 是否有权限
	 */
	public static boolean checkPermissionNoThrowsException(String permission,SecurityPolicy policy){
		try{
			checkPermission(permission,policy);
			return true;
		}catch (AuthenticationException e) {
			return false;
		}catch(AuthorizationException e){
			return false;
		}
	}
	
	/**
	 * 按照校验策略校验权限
	 * @param permission
	 * @param policy
	 */
	public static void checkPermission(String permission,SecurityPolicy policy){
		Subject subject = SecurityUtils.getSubject();
		//要求必须登录
		if(!subject.isAuthenticated()){
			throw new AuthenticationException();
		}
		//要求必须登录,且不能是remember me方式 
		if(policy.equals(SecurityPolicy.Mandatory) && subject.isRemembered()){
			throw new AuthenticationException();
		}
		//登录即可
		if(policy.equals(SecurityPolicy.AllLogonUser)){
			return;
		}else{
			//校验权限
			if(!subject.isPermitted(permission)){
				   throw new AuthorizationException(subject.getPrincipal().toString(),permission);
			}
		}
	}
}
